#include "lexer.h"
#include "../common/list.h"

#include "../typedef/token.h"

#include "lexercomment.h"
#include "lexerkeyvariable.h"
#include "lexeroperation.h"
#include "lexerstring.h"
#include "lexervalue.h"

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

struct _lexer
{
	//解读出来的记号列表
	List *ptokenlist;
	ListCursor *pcursor;

};

Lexer *LexerInit()
{
	Lexer *plex;
	plex = (Lexer*) malloc(sizeof(Lexer));
	plex->ptokenlist=ListInit();
	plex->pcursor=0;
	return plex;
}

void LexerPush(Lexer *plex, Token *ptoken)
{
	assert(plex);
	assert(ptoken);
	assert(plex->ptokenlist);
	ListPush(plex->ptokenlist, ptoken);
}

//对buff区进行词法解析,并把结果放入到lexer中
Lexer *LexerParser(char *buff, int size)
{
	assert(buff);
	Lexer *plex;
	plex = LexerInit();
	int line; //当前行数
	line = 0;
	int len; //当前已经读取大小
	len = 0;
	char *ch;
	ch = buff;

	while (len <size) {
		switch (*ch)
		{
			case '\n': {
				line++;
				len++;
				ch++;
				continue;
			}
			case ' ':
			case '\t': {
				len++;
				ch++;
				continue;
			}

			default: {
				char *tch;
				tch = LexerOperation(ch, &line, &len, plex, size);
				if (tch == 0) {
					printf("编译失败1.\n");
					return 0;
				}
				if (tch != ch) {
					ch = tch;
					continue;
				}
				else {
					//不是符号
					tch = 0;
				}
				//检查字符串
				tch = LexerString(ch, &line, &len, plex, size);
				if (tch == 0) {
					printf("编译失败2.\n");
					return 0;
				}
				if (tch != ch) {
					ch = tch;
					continue;
				}
				else {
					//不是关键字或变量
					tch = 0;
				}


				//检查整数
				tch = LexerValue(ch, &line, &len, plex, size);
				if (tch == 0) {
					printf("编译失败3.\n");
					return 0;
				}
				if (tch != ch) {
					ch = tch;
					continue;
				}
				else {
					//不是关键字或变量
					tch = 0;
				}
				//关键字和变量识别
				tch = LexerKeyVariable(ch, &line, &len, plex, size);
				if (tch == 0) {
					printf("编译失败4.\n");
					return 0;
				}
				if (tch != ch) {
					ch = tch;
					continue;
				}
				else {
					//不是关键字或变量
					tch = 0;
				}

				//检查浮点数
				printf("未知的字符%c(%d).\n", ch, *ch);
				return 0;
			}
		}

	}
	return plex;
}

//获取位置最靠前的记号,
Token *LexerGetToken(Lexer *plexer)
{
	assert(plexer);
	if(plexer->pcursor==0){
		plexer->pcursor=ListGetCursor(plexer->ptokenlist);
	}

	return (Token*) ListForeach(plexer->ptokenlist,plexer->pcursor);
}

void LexerBack(Lexer *plexer)
{
	assert(plexer);
	ListCursorBack(plexer->ptokenlist,plexer->pcursor);
}

void LexerPrint(Lexer *plex,FILE *fl)
{
	assert(plex);
	assert(fl);
	Token *ptoken;
	int len;
	len=ListLength(plex->ptokenlist);
	for(int i=0;i<len;i++){
		ptoken=(Token*) ListExport(plex->ptokenlist);
		ListPush(plex->ptokenlist,ptoken);
		fprintf(fl,"type %d:%s\n",ptoken->type,ptoken->name);
	}
}

void LexerRemove(Lexer *plex,int type)
{
	assert(plex);
	ListCursor *pcursor;
	pcursor=ListGetCursor(plex->ptokenlist);
	Token *ptoken;
	ptoken=(Token*)ListForeach(plex->ptokenlist,pcursor);
	while(ptoken)
	{
		if(ptoken->type==type){
			ptoken=(Token*)ListRemoveCursor(pcursor);
			free(ptoken);
		}
		ptoken=(Token*)ListForeach(plex->ptokenlist,pcursor);
	}

}
